package com.slh.touchandroid.fragment;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.slh.touchandroid.R;
import com.slh.touchandroid.model.FileInfo;
import com.slh.touchandroid.utils.AppUtils;
import com.slh.touchandroid.utils.CONFIG;
import com.slh.touchandroid.utils.FileUtils;

public class BrowserFragment extends Fragment implements
		OnItemClickListener {
	// ==========================================================
	public static final int ID_DETAIL = 0;
	public static final int ID_ZIP = 1;
	public static final int ID_RENAME = 2;
	public static final int ID_DELETE = 3;
	public static final String ROOT_FILE = Environment
			.getExternalStorageDirectory().getAbsolutePath();
	private ListView mFileListView;
	private ArrayList<FileInfo> mFileInfos;
	private FileAdapter mFileAdapter;
	private ReadFileTask mFileReader;
	private String mPath;
	private boolean isRoot;

	// ==========================================================
	public static BrowserFragment newInstance(String path) {
		BrowserFragment browserFragment = new BrowserFragment();
		Bundle bundle = new Bundle();
		bundle.putString("path", path);
		browserFragment.setArguments(bundle);

		return browserFragment;
	}

	public static BrowserFragment newInstance(String path, String name,
			boolean isRoot) {
		BrowserFragment browserFragment = new BrowserFragment();
		Bundle bundle = new Bundle();
		bundle.putString("path", path);
		bundle.putString("name", name);
		bundle.putBoolean("root", isRoot);
		browserFragment.setArguments(bundle);
		return browserFragment;
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		mPath = getArguments().getString("path");
		isRoot = getArguments().getBoolean("root");
		super.onCreate(savedInstanceState);
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View rootView = inflater.inflate(R.layout.fragment_list, container,
				false);
		mFileListView = (ListView) rootView
				.findViewWithTag(getString(R.string.tag_list));
		mFileListView.setOnItemClickListener(this);
		getFiles(mPath);
		return rootView;
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		AdapterContextMenuInfo contextMenuInfo = (AdapterContextMenuInfo) menuInfo;
		int postion = contextMenuInfo.position;
		menu.add(0, ID_DETAIL, 0, "Details");
		menu.add(0, ID_RENAME, 1, "Rename");
		menu.add(0, ID_ZIP, 2, "Zip");
		menu.add(0, ID_DELETE, 3, "Delete");
		super.onCreateContextMenu(menu, v, menuInfo);
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		AdapterContextMenuInfo contextMenuInfo = (AdapterContextMenuInfo) item
				.getMenuInfo();
		int postion = contextMenuInfo.position;
		switch (item.getItemId()) {
		case ID_DETAIL:
			FileUtils.showDetail(getActivity(), mFileInfos.get(postion).path);
			break;
		case ID_RENAME:
			FileUtils.renameFile(getActivity(), mFileInfos.get(postion).path);
			break;
		case ID_DELETE:
			FileUtils.deleteFile(getActivity(), mFileInfos.get(postion).path);
			break;
		default:
			break;
		}
		return super.onContextItemSelected(item);
	}

	// ==========================================================
	private void getFiles(String path) {
		mFileReader = new ReadFileTask();
		mFileReader.execute(path);
	}

	// ==========================================================
	private class ReadFileTask extends
			AsyncTask<String, Void, ArrayList<FileInfo>> {

		@Override
		protected ArrayList<FileInfo> doInBackground(String... params) {
			ArrayList<FileInfo> infos = new ArrayList<FileInfo>();
			File folder = new File(params[0]);
			if (!folder.isDirectory()) {
				return infos;
			}
			File[] children = folder.listFiles();
			if (children == null || children.length == 0) {
				return infos;
			}
			for (File file : children) {
				FileInfo fileInfo = new FileInfo(file.getAbsolutePath(),
						file.getName(), FileUtils.getMimeType(file
								.getAbsolutePath()), file.isDirectory());
				fileInfo.lastModified = DateUtils.formatDateTime(getActivity(),
						file.lastModified(), DateUtils.FORMAT_SHOW_DATE
								| DateUtils.FORMAT_SHOW_YEAR);
				if (file.isDirectory()) {
					File[] files = file.listFiles();
					if (files == null) {
						fileInfo.size = String.format("%d item", 0);
					} else {
						fileInfo.size = String.format("%d items",
								file.listFiles().length);
					}

				} else {
					fileInfo.size = AppUtils.convertSizeIntoString(file
							.length());
				}
				infos.add(fileInfo);
			}
			Collections.sort(infos, new Comparator<FileInfo>() {

				@Override
				public int compare(FileInfo lhs, FileInfo rhs) {
					if (lhs.isDirectory ^ rhs.isDirectory) {
						int l = lhs.isDirectory ? 1 : 0;
						int r = rhs.isDirectory ? 1 : 0;
						return r - l;
					}

					return lhs.name.compareTo(rhs.name);
				}
			});
			return infos;
		}

		@Override
		protected void onPostExecute(ArrayList<FileInfo> result) {
			mFileInfos = result;
			if (!isRoot) {
				mFileInfos.add(0, new FileInfo("", "...", "", false, true));
			}
			mFileAdapter = new FileAdapter(getActivity(), mFileInfos);
			mFileListView.setAdapter(mFileAdapter);
			registerForContextMenu(mFileListView);
			super.onPostExecute(result);
		}

	}

	// ==========================================================
	static class Holder {
		TextView tvName;
		TextView tvDesc;
		TextView tvDesc2;
		ImageView imgIcon;
		CheckBox cbChoise;
	}

	private static class FileAdapter extends BaseAdapter {
		private Context context;
		private ArrayList<FileInfo> fileInfos;

		public FileAdapter(Context context, ArrayList<FileInfo> fileInfos) {
			super();
			this.context = context;
			this.fileInfos = fileInfos;
		}

		@Override
		public int getCount() {
			return fileInfos.size();
		}

		@Override
		public Object getItem(int position) {
			return fileInfos.get(position);
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			Holder holder;
			if (null == convertView) {
				convertView = LayoutInflater.from(context).inflate(
						R.layout.row_browser, null);
				holder = new Holder();
				holder.tvName = (TextView) convertView.findViewWithTag(context
						.getString(R.string.tag_name));
				holder.tvDesc = (TextView) convertView.findViewWithTag(context
						.getString(R.string.tag_desc));
				holder.tvDesc2 = (TextView) convertView.findViewWithTag(context
						.getString(R.string.tag_desc2));
				holder.imgIcon = (ImageView) convertView
						.findViewWithTag(context.getString(R.string.tag_icon));
				holder.cbChoise = (CheckBox) convertView
						.findViewWithTag(context
								.getString(R.string.tag_checkbox));
				convertView.setTag(holder);
			} else {
				holder = (Holder) convertView.getTag();
			}

			final FileInfo info = fileInfos.get(position);
			String mimeType = info.mimeType;
			if (info.isDirectory) {
				// holder.tvName.setCompoundDrawablesWithIntrinsicBounds(
				// R.drawable.ic_folder_dim, 0, 0, 0);
				holder.imgIcon.setImageResource(R.drawable.ic_folder_dim);
			} else if (info.isBackFolder) {
				// holder.tvName.setCompoundDrawablesWithIntrinsicBounds(0, 0,
				// 0,
				// 0);
				holder.imgIcon.setImageResource(0);
			} else if (TextUtils.isEmpty(mimeType)) {
				// holder.tvName.setCompoundDrawablesWithIntrinsicBounds(
				// R.drawable.ic_unknown, 0, 0, 0);
				holder.imgIcon.setImageResource(R.drawable.ic_unknown);
			} else if (mimeType.contains(CONFIG.MIMETYPE.AVI)) {
				// holder.tvName.setCompoundDrawablesWithIntrinsicBounds(
				// R.drawable.ic_avi, 0, 0, 0);
				holder.imgIcon.setImageResource(R.drawable.ic_avi);
			} else if (mimeType.contains(CONFIG.MIMETYPE.CSV)) {
				// holder.tvName.setCompoundDrawablesWithIntrinsicBounds(
				// R.drawable.ic_csv, 0, 0, 0);
				holder.imgIcon.setImageResource(R.drawable.ic_csv);
			} else if (mimeType.contains(CONFIG.MIMETYPE.XLS)
					|| mimeType.contains(CONFIG.MIMETYPE.XLSX)) {
				// holder.tvName.setCompoundDrawablesWithIntrinsicBounds(
				// R.drawable.ic_exel, 0, 0, 0);
				holder.imgIcon.setImageResource(R.drawable.ic_exel);
			} else if (mimeType.contains(CONFIG.MIMETYPE.FLV)) {
				// holder.tvName.setCompoundDrawablesWithIntrinsicBounds(
				// R.drawable.ic_flv, 0, 0, 0);
				holder.imgIcon.setImageResource(R.drawable.ic_flv);
			} else if (mimeType.contains(CONFIG.MIMETYPE.GIF)) {
				// holder.tvName.setCompoundDrawablesWithIntrinsicBounds(
				// R.drawable.ic_gif, 0, 0, 0);
				holder.imgIcon.setImageResource(R.drawable.ic_gif);
			} else if (mimeType.contains(CONFIG.MIMETYPE.JPG)) {
				// holder.tvName.setCompoundDrawablesWithIntrinsicBounds(
				// R.drawable.ic_jpg, 0, 0, 0);
				holder.imgIcon.setImageResource(R.drawable.ic_jpg);
			} else if (mimeType.contains(CONFIG.MIMETYPE.PNG)) {
				// holder.tvName.setCompoundDrawablesWithIntrinsicBounds(
				// R.drawable.ic_png, 0, 0, 0);
				holder.imgIcon.setImageResource(R.drawable.ic_png);
			} else if (mimeType.contains(CONFIG.MIMETYPE.PDF)) {
				// holder.tvName.setCompoundDrawablesWithIntrinsicBounds(
				// R.drawable.ic_pdf, 0, 0, 0);
				holder.imgIcon.setImageResource(R.drawable.ic_pdf);
			} else if (mimeType.contains(CONFIG.MIMETYPE.PPT)
					|| mimeType.contains(CONFIG.MIMETYPE.PPTX)) {
				// holder.tvName.setCompoundDrawablesWithIntrinsicBounds(
				// R.drawable.ic_pp, 0, 0, 0);
				holder.imgIcon.setImageResource(R.drawable.ic_pp);
			} else if (mimeType.contains(CONFIG.MIMETYPE.DOC)
					|| mimeType.contains(CONFIG.MIMETYPE.DOCX)) {
				// holder.tvName.setCompoundDrawablesWithIntrinsicBounds(
				// R.drawable.ic_word, 0, 0, 0);
				holder.imgIcon.setImageResource(R.drawable.ic_word);
			} else if (mimeType.contains(CONFIG.MIMETYPE.ZIP)) {
				// holder.tvName.setCompoundDrawablesWithIntrinsicBounds(
				// R.drawable.ic_zip, 0, 0, 0);
				holder.imgIcon.setImageResource(R.drawable.ic_zip);
			} else if (mimeType.contains(CONFIG.MIMETYPE.ZIP_7)) {
				// holder.tvName.setCompoundDrawablesWithIntrinsicBounds(
				// R.drawable.ic_seven_zip, 0, 0, 0);
				holder.imgIcon.setImageResource(R.drawable.ic_seven_zip);
			} else if (mimeType.contains(CONFIG.MIMETYPE.WMA)) {
				// holder.tvName.setCompoundDrawablesWithIntrinsicBounds(
				// R.drawable.ic_wma, 0, 0, 0);
				holder.imgIcon.setImageResource(R.drawable.ic_wma);
			} else if (mimeType.contains(CONFIG.MIMETYPE.RAR)) {
				// holder.tvName.setCompoundDrawablesWithIntrinsicBounds(
				// R.drawable.ic_rar, 0, 0, 0);
				holder.imgIcon.setImageResource(R.drawable.ic_rar);
			} else {
				// holder.tvName.setCompoundDrawablesWithIntrinsicBounds(
				// R.drawable.ic_unknown, 0, 0, 0);
				holder.imgIcon.setImageResource(R.drawable.ic_unknown);
			}
			holder.tvName.setText(info.name);
			if (!info.isBackFolder) {
				holder.cbChoise.setVisibility(View.VISIBLE);
				holder.tvDesc.setText(info.size);
				holder.tvDesc2.setText(info.lastModified);
			} else {
				holder.cbChoise.setVisibility(View.GONE);
				holder.tvDesc.setText("");
				holder.tvDesc2.setText("");
			}
			holder.cbChoise.setChecked(info.isChecked);
			holder.cbChoise.setOnClickListener(new View.OnClickListener() {

				@Override
				public void onClick(View v) {
					info.isChecked = !info.isChecked;
				}
			});
			return convertView;
		}
	}

	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position,
			long id) {
		FileInfo fileInfo = mFileInfos.get(position);
		if (fileInfo.isDirectory) {
			getActivity()
					.getSupportFragmentManager()
					.beginTransaction()
					.replace(R.id.content_frame,
							BrowserFragment.newInstance(fileInfo.path))
					.addToBackStack("").commit();
		} else if (fileInfo.isBackFolder) {
			getActivity().onBackPressed();
		} else {
			FileUtils.openFile(getActivity(), fileInfo.path, fileInfo.mimeType);
			// AppUtils.share(getActivity(), fileInfo.path);
		}

	}

}
